package tools.redistools;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static tools.CompareUtils.greaterThanZero;


@Component
@Slf4j
public class RedisDisLock {

    @Autowired
    private RedisAPI redisAPI;

    public static final String COLON_DELIMITER_CODE = ":";


    /**
     * redis分布式锁（加锁）
     *
     * @param loginUserId
     * @param buildingId
     * @param houseId
     * @param roomId
     */
    public void redisDistributeLock(String key, Long loginUserId, Long contractId, Long buildingId, Long houseId, Long roomId, Long expireTime) {
        redisDistributeLock(key, loginUserId, contractId, buildingId, houseId, roomId, expireTime, COLON_DELIMITER_CODE);
    }

    /**
     * redis分布式锁（加锁）
     *
     * @param loginUserId
     * @param buildingId
     * @param houseId
     * @param roomId
     */
    public void redisDistributeLock(String key, Long loginUserId, Long contractId, Long buildingId, Long houseId, Long roomId, Long expireTime, String delimiter) {
        if (greaterThanZero(loginUserId)) {
            if (isBlank(delimiter)) {
                delimiter = COLON_DELIMITER_CODE;
            }
            String redis_key = key + delimiter + loginUserId + delimiter + contractId + delimiter + buildingId + delimiter + houseId + delimiter + roomId;
            log.info(key + " = " + redis_key);
            boolean b = redisAPI.setDistributedLock(redis_key, String.valueOf(key.hashCode()), expireTime);
            if (!b) {
                throw new RuntimeException("加锁失败");
            }
        }
    }

    /**
     * redis分布式锁（加锁）
     *
     * @param loginUserId
     * @param typeKey
     * @param dataKey
     * @param expireTime
     */
    public void redisDistributeLock(String typeKey, Long loginUserId, String dataKey, Long expireTime) {
        if (greaterThanZero(loginUserId)) {
            String redis_key = typeKey + ":" + loginUserId + ":" + dataKey;
            int redis_value = typeKey.hashCode();
            boolean b = redisAPI.setDistributedLock(redis_key, String.valueOf(redis_value), expireTime);
            if (!b) {
                throw new RuntimeException("加锁失败");
            }
        }
    }


    /**
     * redis分布式锁（解锁）
     *
     * @param key
     * @param loginUserId
     * @param contractId
     * @param buildingId
     * @param houseId
     * @param roomId
     * @return 0-key已经被删除或者超时自动移除或者不存在 1-key删除成功 99-不存在该key
     */
    public Object delRedisDistributeLock(String key, Long loginUserId, Long contractId, Long buildingId, Long houseId, Long roomId) {
        return delRedisDistributeLock(key, loginUserId, contractId, buildingId, houseId, roomId, COLON_DELIMITER_CODE);
    }

    /**
     * redis分布式锁（解锁）
     *
     * @param key
     * @param loginUserId
     * @param contractId
     * @param buildingId
     * @param houseId
     * @param roomId
     * @return 0-key已经被删除或者超时自动移除或者不存在 1-key删除成功 99-不存在该key
     */
    public Object delRedisDistributeLock(String key, Long loginUserId, Long contractId, Long buildingId, Long houseId, Long roomId, String delimiter) {
        if (isNotBlank(key)) {
            if (isBlank(delimiter)) {
                delimiter = COLON_DELIMITER_CODE;
            }
            String redis_key = key + delimiter + loginUserId + delimiter + contractId + delimiter + buildingId + delimiter + houseId + delimiter + roomId;
            //集群不支持 scripot
            return redisAPI.del(redis_key);
        }
        return 99;
    }


    /**
     * redis加锁
     *
     * @param key
     * @param expireTime
     * @param delimiter
     * @param params
     */
    public void redisDistributeLock(String key, Long expireTime, String delimiter, List<Long> params) {
        if (isNotBlank(key) && !CollectionUtils.isEmpty(params)) {
            if (!greaterThanZero(expireTime)) {
                expireTime = 30L;
            }
            String redis_key = getRedisKey(key, delimiter, params);

            int redis_value = redis_key.hashCode();
            boolean b = redisAPI.setDistributedLock(redis_key, String.valueOf(redis_value), expireTime);
            if (!b) {
                throw new RuntimeException("加锁失败");
            }
        }
    }

    private String getRedisKey(String key, String delimiter, List<Long> params) {
        if (isBlank(delimiter)) {
            delimiter = COLON_DELIMITER_CODE;
        }
        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append("PROJECT_NAME").append(delimiter).append(key).append(delimiter);
        for (Long id : params) {
            stringBuffer.append(id).append(delimiter);
        }
        return stringBuffer.substring(0, stringBuffer.toString().length() - 1);
    }

    /**
     * redis 解锁
     *
     * @param key
     * @param delimiter
     * @param params
     */
    public Object delRedisDistributeLock(String key, String delimiter, List<Long> params) {
        if (isNotBlank(key) && !CollectionUtils.isEmpty(params)) {
            String redis_key = getRedisKey(key, delimiter, params);
            //集群不支持 script
            return redisAPI.del(redis_key);
        }
        return null;
    }
}
